package com.jyy.prefabricated.controller;

import com.alibaba.fastjson.JSONObject;
import com.bocom.api.BocomApiException;
import com.bocom.api.DefaultBocomClient;
import com.bocom.api.utils.ApiUtils;
import com.bocom.api.utils.StringUtils;
import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
import com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderResult;
import com.github.binarywang.wxpay.constant.WxPayConstants;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.jyy.prefabricated.common.AjaxResult;
import com.jyy.prefabricated.entity.OrderInfo;
import com.jyy.prefabricated.entity.SysUser;
import com.jyy.prefabricated.request.pmssMpng.MPNG210003RequestV1;
import com.jyy.prefabricated.request.pmssMpng.MPNG210003RequestV1.MPNG210003RequestV1Biz.ReqBody;
import com.jyy.prefabricated.request.pmssMpng.MPNG210003RequestV1.MPNG210003RequestV1Biz.ReqBody.RequireFields;
import com.jyy.prefabricated.request.pmssMpng.MPNG210003RequestV1.MPNG210003RequestV1Biz.ReqHead;
import com.jyy.prefabricated.request.pmssMpng.MisCreateOrderRequestV1;
import com.jyy.prefabricated.request.pmssMpng.PmmsMpngNotifyRequestV1;
import com.jyy.prefabricated.response.pmssMpng.MPNG210003ResponseV1;
import com.jyy.prefabricated.response.pmssMpng.MisCreateOrderResponseV1;
import com.jyy.prefabricated.response.pmssMpng.MisNotifyContentResponse;
import com.jyy.prefabricated.response.pmssMpng.PmmsMpngNotifyResponseV1;
import com.jyy.prefabricated.service.OrderInfoService;
import com.jyy.prefabricated.service.PayService;
import com.jyy.prefabricated.utils.DateUtils;
import com.jyy.prefabricated.utils.IpUtil;
import com.jyy.prefabricated.utils.JsonUtils;
import com.jyy.prefabricated.utils.UserUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.RandomStringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.util.*;

/**
 * 微信支付
 */
@Slf4j
@RequestMapping("/api")
@RestController
public class WxPayController {

    @Autowired
    private OrderInfoService orderInfoService;

    @Autowired
    private WxPayService wxPayService;

    @Autowired
    private PayService payService;
    @Autowired
    private UserUtils userUtils;
    @Value("${xft.pay.myPrivateKey}")
    public String myPrivateKey;

    @Value("${xft.pay.apigwPublicKey}")
    public String apigwPublicKey;

    @Value("${xft.pay.bocomPrdKey}")
    public String bocomPrdKey;

    @Value("${xft.pay.appId}")
    public String appId;

    @Value("${xft.pay.mchtId}")
    public String mchtId;
    @Value("${xft.pay.apigwUrlAddress}")
    public String apigwUrlAddress;

    @Value("${xft.pay.notifyUrl}")
    public String notifyUrl;
    @Value("${xft.pay.misNotifyUrl}")
    public String misNotifyUrl;
    /**
     * 校付通数币支付
     * @param orderCode
     * @return
     * @throws WxPayException
     */
    @GetMapping("/wxpay/orderMisPay/{orderCode}")
    public AjaxResult orderMisPay(@PathVariable String orderCode,HttpServletRequest httpServletRequest) throws WxPayException {
        try {
            OrderInfo orderInfo = orderInfoService.selectByOrderCode(orderCode);
            DefaultBocomClient client = new DefaultBocomClient(appId, myPrivateKey, bocomPrdKey);
            /**
             * 测试环境可以忽略SSL证书告警，生产环境不可忽略
             */
            client.ignoreSSLHostnameVerifier();

            MisCreateOrderRequestV1 request = new MisCreateOrderRequestV1();
            request.setServiceUrl(apigwUrlAddress + "/api/walletpay/misCreateOrder/v1");

            MisCreateOrderRequestV1.MisCreateOrderRequestV1Biz bizContent = new MisCreateOrderRequestV1.MisCreateOrderRequestV1Biz();
            MisCreateOrderRequestV1.MisCreateOrderRequestV1Biz.ReqHead req_head = new MisCreateOrderRequestV1.MisCreateOrderRequestV1Biz.ReqHead();

            req_head.setTermTransTime(DateUtils.formatDate(new Date(),"yyyyMMddHHmmss"));
            req_head.setTraceNo(RandomStringUtils.randomAlphanumeric(28).replace("-", ""));
            bizContent.setReqHead(req_head);
            MisCreateOrderRequestV1.MisCreateOrderRequestV1Biz.ReqBody req_body = new MisCreateOrderRequestV1.MisCreateOrderRequestV1Biz.ReqBody();

            req_body.setTotalAmount(orderInfo.getTotalPrice().multiply(new BigDecimal(100)).setScale( 0, BigDecimal.ROUND_UP ).toString());
            req_body.setAmountType("156");
            req_body.setChannel("05");
            req_body.setMchtId(mchtId);
            req_body.setPartnerId("");
            req_body.setTermBatchNo("");
            req_body.setTermPosNo("");
            req_body.setAuthId(null);
            req_body.setMchtOrderNo(orderInfo.getOrderCode());
            req_body.setNotifyUrl(appId+"@"+misNotifyUrl);
            bizContent.setReqBody(req_body);
            request.setBizContent(bizContent);
            log.info("校付通下单 request:{}",JSONObject.toJSON(request));
            MisCreateOrderResponseV1 response = client.execute(request,UUID.randomUUID().toString().replace("-", ""));
            if (response.isSuccess()) {
                System.out.println("success");
                System.out.println(response.toString());
                log.info("校付通下单 response:{}",JSONObject.toJSON(response));
                return AjaxResult.success(response);
            } else {
                System.out.println(response.getRspCode());
                System.out.println(response.getRspMsg());
                log.info("校付通下单 response:{}",response);
                return AjaxResult.error(response.getRspMsg());
            }
        } catch (Exception xcp) {
            xcp.printStackTrace();
        }
        return AjaxResult.error("请求失败");
    }
    /**
     * 校付通支付
     * @param orderCode
     * @return
     * @throws WxPayException
     */
    @GetMapping("/wxpay/orderPay/{orderCode}")
    public AjaxResult orderPay(@PathVariable String orderCode,HttpServletRequest httpServletRequest) throws WxPayException {
        try {
            OrderInfo orderInfo = orderInfoService.selectByOrderCode(orderCode);
            DefaultBocomClient client = new DefaultBocomClient(appId, myPrivateKey, bocomPrdKey);
            /**
             * 测试环境可以忽略SSL证书告警，生产环境不可忽略
             */
            client.ignoreSSLHostnameVerifier();

            MPNG210003RequestV1 request = new MPNG210003RequestV1();
            request.setServiceUrl(apigwUrlAddress + "/api/pmssMpng/MPNG210003/v1");

            MPNG210003RequestV1.MPNG210003RequestV1Biz bizContent = new MPNG210003RequestV1.MPNG210003RequestV1Biz();
            ReqHead reqHead = new ReqHead();
            bizContent.setReqHead(reqHead);

            reqHead.setTransTime(DateUtils.formatDate(new Date(),"yyyyMMddHHmmss"));
            reqHead.setVersion("V-1.0");
            ReqBody reqBody = new ReqBody();
            bizContent.setReqBody(reqBody);
            reqBody.setValidPeriod("");
            /*SettleInfo settle_info = new SettleInfo();
            reqBody.setSettleInfo(settle_info);
            settle_info.setOppBankNo("");
            settle_info.setOppBankName("");
            settle_info.setAccountName("");
            settle_info.setAccountNo("");
            settle_info.setTransType("");*/
            /**
             * B2C-JSAPI-ALIPAY   支付宝内置浏览器上展示支付宝生活号支付页面 B2C-JSAPI-WECHAT   微信内置浏览器上展示微信公众号支付页面 B2C-H5-ALIPAY    手机浏览器跳转支付宝wap支付和app支付 B2C-PC-ALIPAY    PC浏览器跳转支付宝网页支付
             */
            reqBody.setTranScene("B2C-JSAPI-WECHAT");
            reqBody.setMerPtcId(mchtId);//131058140000089
            reqBody.setMerTradeTime(DateUtils.formatDate(new Date(),"HHmmss"));
            reqBody.setNotifyUrl(notifyUrl);
            reqBody.setMerTradeDate(DateUtils.formatDate(new Date(),"yyyyMMdd"));
            reqBody.setShopId("");
            reqBody.setPartnerId("");
            reqBody.setPayMerTranNo(orderInfo.getOrderCode());
            reqBody.setJumpUrl("");
            reqBody.setMerMemo("商户备注");
            reqBody.setTotalAmount(orderInfo.getTotalPrice().toString());

            List<RequireFields> require_fieldsList = new ArrayList<RequireFields>();
            RequireFields require_fields = new RequireFields();
            require_fieldsList.add(require_fields);
            reqBody.setRequireFields(require_fieldsList);
            require_fields.setRequireField("");
            reqBody.setLocation("ONLINE");
            reqBody.setCurrency("CNY");
            reqBody.setTranContent("商品名称："+orderInfo.getProductName());
            reqBody.setNoDsctAmount("");
            request.setBizContent(bizContent);
            log.info("校付通下单 request:{}", JSONObject.toJSON(request));
            MPNG210003ResponseV1 response = client.execute(request, UUID.randomUUID().toString().replace("-", ""));
            if (response.isSuccess()) {
                System.out.println("success");
                System.out.println(response.toString());
                log.info("校付通下单 response:{}",JSONObject.toJSON(response));
                return AjaxResult.success(response);
            } else {
                System.out.println(response.getRspCode());
                System.out.println(response.getRspMsg());
                log.info("校付通下单 response:{}",response);
                return AjaxResult.error(response.getRspMsg());
            }
        } catch (Exception xcp) {
            xcp.printStackTrace();
        }
        return AjaxResult.error("请求失败");
    }
    /**
     * 微信统一下单native支付
     * @param orderCode
     * @return
     * @throws WxPayException
     */
    @GetMapping("/wxpay/tradeOrder/{orderCode}")
    public AjaxResult tradePay(@PathVariable String orderCode, @RequestParam String tradeType, HttpServletRequest httpServletRequest) throws WxPayException {
        String ip = IpUtil.getIpAddress(httpServletRequest);
        log.info("微信支付统一下单 orderCode:{},ip:{}",orderCode,ip);
        OrderInfo orderInfo = orderInfoService.selectByOrderCode(orderCode);
        if(WxPayConstants.TradeType.JSAPI.equals(tradeType)){
            Map<String,String> result =payService.tradePayJSAPI(orderInfo,tradeType,ip);
            return AjaxResult.success(result);
        }
        SysUser user = userUtils.getCurrentUser();
        WxPayUnifiedOrderResult result = payService.tradePay(orderInfo,tradeType,ip,user.getTeamCode());
        return AjaxResult.success(result);
    }

    /**
     * 微信支付回调
     * @param xmlData
     * @return
     * @throws WxPayException
     */
    @PostMapping("/wxpay/checkOrder/notify")
    public String checkOrder(@RequestBody String xmlData) throws WxPayException {
        log.info("微信支付回调传参信息：{}",xmlData);
        final WxPayOrderNotifyResult notifyResult = wxPayService.parseOrderNotifyResult(xmlData);
        log.info("微信支付回调信息：{}",notifyResult);
        orderInfoService.paid(notifyResult.getOutTradeNo());
        return WxPayNotifyResponse.success("成功");
    }

    /**
     * 校付通微信支付回调
     * @param request
     * @return
     * @throws WxPayException
     */
    @PostMapping("/wxpay/notifyOrder/notify")
    public void notifyOrder(HttpServletRequest request, HttpServletResponse response) throws IOException {
        log.info("校付通支付回调传参信息：{}",request);
        Writer writer= new BufferedWriter(new OutputStreamWriter(response.getOutputStream()));
        writer.append("Served at: ").append(request.getContextPath());
        InputStream inputStream;
        StringBuffer sb = new StringBuffer();
        inputStream = request.getInputStream();
        String s;
        BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
        while ((s = in.readLine()) != null) {
            sb.append(s);
        }
        System.out.println(sb.toString());
        //{"notify_biz_content":{"notify_url":"http://lilehao.natapp4.cc/EPay/PmssNotify","tran_type":"PAY","mer_tran_no":"123420211103141153","tran_state":"SUCCESS","tran_state_code":"SUCCESS","tran_state_msg":"成功","partner_id":"","mer_ptc_id":"131058140006387","final_time":"20211103141228","total_amount":"1.00","buyer_pay_amount":"1.00","trd_dsct_amount":"0.00","pay_dsct_amount":"0.00","currency":"CNY","tran_content":"tran_content","mer_memo":"mer_memo","require_values":{"bank_tran_no":null,"third_party":null,"third_party_tran_no":null,"payment_info":null,"refund_info":null}},"sign":"piUNZdUl1i/y/WbrHXBsoIdxSsrMAa4qCOc4ouhJ3KFUsrOrdx1VNaA7We8VpfI+0WRU+z+DgJAtR+hjH4VgVS324xJ1H6PoKSiigaY+/89Hi/xx8pCWJJCTiZ3nGIt1D6NxS3R0aQoyoWJd6q0n/2H2A2kYYx/SX6tI5WF5+3Nl9Osp6L8DZxa3ZPyUQK2f+rAUiKJ1mHgjhqSUyYoQdENUnvhPcFRY47+UFDNzCTXPSVrycKlBTP+y0Ep0cNWpf/qju77kUod4yiEujdlFXKErxzqWrhBRLGTh2QI6FwW2RK6rAxIy7fQzLKuxg1hDBIiqKvskfFB3HnWYNviarg=="}
        try {
            PmmsMpngNotifyRequestV1.PmmsMpngNotifyRequestV1Biz prequest = (PmmsMpngNotifyRequestV1.PmmsMpngNotifyRequestV1Biz)ApiUtils.parseNotifyJsonWithBocomSign(sb.toString(),"UTF-8",bocomPrdKey,PmmsMpngNotifyRequestV1.PmmsMpngNotifyRequestV1Biz.class);

            orderInfoService.paid(prequest.getMerTranNo());
        }catch(Exception e) {

        }
        in.close();
        inputStream.close();
        String resp="{'biz_state':'S','rsp_code':'0000','rsp_msg':'success'}";
        System.out.println(resp);
        BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());

        out.write(resp.getBytes());
        out.flush();
        out.close();

        /*PmmsMpngNotifyResponseV1 result = new PmmsMpngNotifyResponseV1();
        try {
            PmmsMpngNotifyRequestV1.PmmsMpngNotifyRequestV1Biz request = (PmmsMpngNotifyRequestV1.PmmsMpngNotifyRequestV1Biz)ApiUtils.parseNotifyJsonWithBocomSign(notifyJson,"UTF-8",apigwPublicKey,PmmsMpngNotifyRequestV1.PmmsMpngNotifyRequestV1Biz.class);

            log.info("校付通支付回调信息：{}",request);
            orderInfoService.paid(request.getMerTranNo());
            result.setBizState("F");
            result.setRspCode("0000");
            result.setRspMsg("success");
            return result;
        } catch (BocomApiException e) {
            e.printStackTrace();
        }
        result.setBizState("S");
        result.setRspCode("0000");
        result.setRspMsg("fail");
        return result;*/
    }
    /**
     * 校付通数币支付回调
     * @param request
     * @return
     * @throws WxPayException
     */
    @PostMapping("/wxpay/notifyOrder/misNotify")
    public String misNotify(HttpServletRequest request, HttpServletResponse response) throws IOException, BocomApiException {
        log.info("校付通数币支付回调传参信息：{}",request);
        Writer writer= new BufferedWriter(new OutputStreamWriter(response.getOutputStream()));
        writer.append("Served at: ").append(request.getContextPath());
        InputStream inputStream;
        StringBuffer sb = new StringBuffer();
        inputStream = request.getInputStream();
        String s;
        BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
        while ((s = in.readLine()) != null) {
            sb.append(s);
        }
        HashMap<String, String> reqMap = ApiUtils.parseCommunicationJsonWithBocomSign(sb.toString(), myPrivateKey, bocomPrdKey);
        String bizContent = reqMap.get("biz_content");
        String encryptKey = reqMap.get("encrypt_key");
        log.info("校付通数币支付回调传参信息bizContent：{}",bizContent);
        JSONObject jsonObject = JSONObject.parseObject(bizContent);
        MisNotifyContentResponse misNotifyContentResponse = JSONObject.toJavaObject(jsonObject, MisNotifyContentResponse.class);

        orderInfoService.paid(misNotifyContentResponse.getOut_trade_no());
        in.close();
        inputStream.close();
        String rspBizContent = "{\"ret_code\":\"0\",\"ret_msg\":\"xxxxxx\"}";
        //对返回报文进行加密加签
        String respMsg = ApiUtils.signRspBizContent(rspBizContent, encryptKey, myPrivateKey);
        return respMsg;
    }
    @PostMapping("/wxpay/notifyOrder/xftNotify")
    public PmmsMpngNotifyResponseV1 notifyOrder(@RequestBody String notifyJson) {
        log.info("校付通支付回调传参信息：{}",notifyJson);
        PmmsMpngNotifyResponseV1 result = new PmmsMpngNotifyResponseV1();
        try {
            PmmsMpngNotifyRequestV1.PmmsMpngNotifyRequestV1Biz request = (PmmsMpngNotifyRequestV1.PmmsMpngNotifyRequestV1Biz)ApiUtils.parseNotifyJsonWithBocomSign(notifyJson,"UTF-8",bocomPrdKey,PmmsMpngNotifyRequestV1.PmmsMpngNotifyRequestV1Biz.class);

            log.info("校付通支付回调信息：{}",request);
            orderInfoService.paid(request.getMerTranNo());
            result.setBizState("S");
            result.setRspCode("0000");
            result.setRspMsg("success");
            return result;
        } catch (BocomApiException e) {
            e.printStackTrace();
        }
        result.setBizState("F");
        result.setRspCode("0000");
        result.setRspMsg("fail");
        return result;
    }
}
